package cn.jishiyu11.xeqb.base

import android.app.Application
import android.content.Context
import android.content.pm.PackageManager
import android.content.pm.PackageManager.NameNotFoundException
import android.os.Build
import android.os.Looper
import android.util.Log

import java.io.PrintWriter
import java.io.StringWriter
import java.lang.Thread.UncaughtExceptionHandler
import java.util.HashMap

import cn.jishiyu11.xeqb.utils.TimeUtils

class UnCeHandler(private val application: Application) : UncaughtExceptionHandler {

    private val mDefaultHandler: UncaughtExceptionHandler?
    private var time: Long = 0

    // 用来存储设备信息和异常信息
    private val deviceInfos = HashMap<String, String>()

    init {
        // 获取系统默认的UncaughtException处理器
        mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler()
    }

    override fun uncaughtException(thread: Thread, ex: Throwable) {
        if (!handleException(ex) && mDefaultHandler != null) {
            // 如果用户没有处理则让系统默认的异常处理器来处理
            mDefaultHandler.uncaughtException(thread, ex)
        } else {
            try {
                Thread.sleep(1000)
            } catch (e: InterruptedException) {
                e.printStackTrace()
            }

            if (System.currentTimeMillis() - time < 1000) {//阻止app同一时间启动多次
                return
            }
            time = System.currentTimeMillis()
            restart(application)
        }
    }

    /**
     * 自定义错误处理,收集错误信息 发送错误报告等操作均在此完成.
     *
     * @param ex
     * @return true:如果处理了该异常信息;否则返回false.
     */
    private fun handleException(ex: Throwable?): Boolean {
        if (ex == null) {
            return false
        }
        // 使用Toast来显示异常信息
        object : Thread() {
            override fun run() {
                Looper.prepare()
                Looper.loop()
            }
        }.start()
        collectDeviceInfo(application.applicationContext)
        val str = formatCrashInfo(ex)
        Log.e("", "=========" + str)
        return true
    }

    /**
     * 格式化日志信息
     *
     * @param context
     */
    fun collectDeviceInfo(context: Context) {
        try {
            val pm = context.packageManager
            val pi = pm.getPackageInfo(context.packageName, PackageManager.GET_ACTIVITIES)
            if (pi != null) {
                val versionName = if (pi.versionName == null) "null" else pi.versionName
                val versionCode = pi.versionCode.toString() + ""
                deviceInfos.put("versionName", versionName)
                deviceInfos.put("versionCode", versionCode)
            }
        } catch (e: NameNotFoundException) {
            e.printStackTrace()
        }

        val fields = Build::class.java.declaredFields
        for (field in fields) {
            try {
                field.isAccessible = true
                deviceInfos.put(field.name, field.get(null).toString())
            } catch (e: Exception) {
                e.printStackTrace()
            }

        }
    }

    /**
     * 获取导致崩溃的错误信息
     * @param ex
     * @return 异常内容
     */
    private fun formatCrashInfo(ex: Throwable): String {
        val exception = StringBuffer()
        for (entry in deviceInfos.entries) {
            val key = entry.key
            var value = entry.value
            if (key == "FINGERPRINT" || key == "TIME" || key == "versionCode"
                    || key == "versionName" || key == "USER" || key == "MODEL" || key == "SERIAL") {
                if (key == "TIME") {
                    value = TimeUtils.currentTimeInString
                }
                exception.append(key).append("=").append(value).append("\n")
            }
        }
        val writer = StringWriter()
        val printWriter = PrintWriter(writer)
        ex.printStackTrace(printWriter)
        printWriter.close()
        val result = writer.toString()
        exception.append(result)
        return exception.toString()
    }

    companion object {

        /**
         * 重启应用程序
         *
         * @param context
         */
        fun restart(context: Context) {
            //		Intent intent = new Intent(context, GuidepageActivity.class);
            //		PendingIntent restartIntent = PendingIntent.getActivity(context, -1, intent, Intent.FLAG_ACTIVITY_NEW_TASK);
            //		 //退出程序
            //		AlarmManager mgr = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
            //		mgr.set(AlarmManager.RTC, System.currentTimeMillis(), restartIntent); // 1秒钟后重启应用
            //		BaseActivityManager.getActivityManager().exitApp();
            //		// 杀死该应用进程
            //		android.os.Process.killProcess(android.os.Process.myPid());
        }

        fun checkPermission(context: Context, permission: String): Boolean {
            var result = false
            if (Build.VERSION.SDK_INT >= 23) {
                try {
                    val clazz = Class.forName("android.content.Context")
                    val method = clazz.getMethod("checkSelfPermission", String::class.java)
                    val rest = method.invoke(context, permission) as Int
                    result = rest == PackageManager.PERMISSION_GRANTED
                } catch (e: Exception) {
                    result = false
                }

            } else {
                val pm = context.packageManager
                if (pm.checkPermission(permission, context.packageName) == PackageManager.PERMISSION_GRANTED) {
                    result = true
                }
            }
            return result
        }
    }
}